using System;
using EnvDTE;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using Microsoft.BizTalk.Studio.Utilities;
using Microsoft.BizTalk.Studio.Extensibility;
using System.Collections;
using System.Collections.Specialized;
using VSLangProj80;
using VSLangProj;
[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)]
namespace BTSProjectWizard
{
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    [Guid("9E08B6E2-F3A7-4acd-85D4-FF150815D94E")]
    public class Wizard : IDTWizard
    {


        Hashtable _Symbols = new Hashtable();
        public void AddSymbol(string name, object val)
        {
            _Symbols[name] = val;
            System.Diagnostics.Debug.WriteLine(String.Format("AddSymbol {0} = {1}", name, val != null ? val.ToString() : "null"));

        }
        public object FindSymbol(string name)
        {
            object ret = _Symbols[name];
            System.Diagnostics.Debug.WriteLine(String.Format("FindSymbol {0} = {1}", name, ret != null ? ret.ToString() : "null"));
            return ret;
        }
        public Wizard()
        {
            TheWizard = this;
        }
        public static Wizard TheWizard
        {
            get { return _TheWizard; }
            set { _TheWizard = value; }

        }
        static Wizard _TheWizard;

        static int PROJECT_NAME = 1;
        static int PROJECT_PATH = 2;
        static int WIZARD_NAME = 0;
        static int PROJECT_TYPE = 1;
        static int SUGGESTED_NAME = 4;
        public WizardInfo Info
        {
            get { return _Info; }
            set { _Info = value; }
        }
        WizardInfo _Info;
        string _templatesdir = @"Templates\";
        string _wizarddir = @"Developer Tools\BizTalkWizards\";
        public void Execute(object Application, int hwndOwner, ref object[] ContextParams, ref object[] CustomParams, ref EnvDTE.wizardResult retval)
        {
            bool isProject = true;

            DTE dte = (DTE)Application;
            string name = GetValue(CustomParams[WIZARD_NAME].ToString());
            string type = GetValue(CustomParams[PROJECT_TYPE].ToString());
            if (type == "ADDITEM")
                isProject = false;
            Solution solution = dte.Solution;
            string suggestedName = null;
            if (!isProject)
            {
                suggestedName = ContextParams[SUGGESTED_NAME].ToString();
            }
            string projpath = ContextParams[PROJECT_PATH].ToString();
            string projname = ContextParams[PROJECT_NAME].ToString();
            string path = Path.Combine(Util.GetBizTalkInstallPath(), _wizarddir);
            string temp = Path.Combine(path, name);
            string templates = Path.Combine(temp, _templatesdir);
            templates = templates = Path.Combine(templates,
Util.GetBizTalkInstallProductLanguage());

            string manifest = Path.Combine(temp, String.Format("{0}.xml", name));
            Project proj = null;
           // IBtsProject btsproj = null;
            try
            {
                WizardInfo wi = Util.LoadFiles(manifest);
                Info = wi;
                bool ok = UIUtil.Run(this, hwndOwner);
                if (ok)
                {

                    if (isProject)
                        proj = solution.AddFromTemplate(Path.Combine(templates, Info.ProjectFile), projpath, projname, false);
                    else
                        proj = dte.SelectedItems.Item(1).Project as Project;
                    VSProject2 btsproj = (VSProject2)proj.Object;
                   // btsproj = (IBtsProject)proj.Object;
                    AddReferences(btsproj);
                    AddFiles(templates, proj, suggestedName);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }
            finally
            {

                _Symbols = new Hashtable();
               // SafeRelease(btsproj);
                SafeRelease(proj);
                SafeRelease(solution);

            }




        }
        void AddFiles(string templates, Project p,string suggestedName)
        {

            for (int i = 0; i < Info.WizardFiles.Count; i++)
            {
                Process(Info.WizardFiles[i], p, templates, suggestedName);
            }
        }
        void Process(WizardFile path, Project p, string templates, string suggestedName)
        {
            IBTWizardFileGen gen = CreateGenerator(path.TypeName);
            bool run = gen.Init(path.Attributes, this);
            if (run)
                gen.AddFile(Path.Combine(templates, path.Path), p, this, suggestedName);
        }
        IBTWizardFileGen CreateGenerator(string type)
        {
            IBTWizardFileGen ret = (IBTWizardFileGen)Activator.CreateInstance(Type.GetType(type));
            return ret;
        }
        string GetValue(string param)
        {
            string[] temp = param.Split('=');
            return temp[1].Trim();
        }
        internal void AddReferences(VSProject2 proj)
        {
            References refs = null;
            try
            {
                refs = (References)proj.References;
                for (int i = 0; i < Info.References.Count; i++)
                    refs.Add(Info.References[i].Path);

            }
            finally
            {
                SafeRelease(refs);
            }
        }
        void SafeRelease(object obj)
        {
            if (obj != null)
                Marshal.ReleaseComObject(obj);
        }



    }
}
